#include <iostream>
#include <stdexcept>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include "sales_data.h"

using namespace std;

istream& pr_8_1(istream &in)
{
    string v;
    while (in >> v, !in.eof()) {  // 直到遇到文件结束符才停止读取
        if (in.bad()) {
            throw runtime_error("IO 流错误");
        }
        if (in.fail()) {
            cerr << "数据错误，请重试：" << endl;
            in.clear();
            in.ignore(100, '\n');
            continue;
        }
        cout << v << endl;
    }
    in.clear();
    return in;
}

int pr_8_4()
{
    ifstream in("data");  // 打开文件
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    string line;  // 每一行
    vector<string> words;
    while (getline(in, line)) {  // 从文件中读取一行
        words.push_back(line);  // 添加到vector中
    }
    in.close();  // 输入完毕，关闭文件
    vector<string>::const_iterator it = words.begin();  // 迭代器
    while (it != words.end()) {  // 遍历vector
        cout << *it << endl;  // 输出vector中的元素
        ++it;
    }
    return 0;
}

int pr_8_5()
{
    ifstream in("data");
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    string word;
    vector<string> words;
    while (in >> word) {  // 读取每个单词
        words.push_back(word);
    }
    in.close();

    return 0;
}

int pr_8_6(int argc, char **argv)
{
    if (argc != 2) {
        cerr << "请给出文件名" << endl;
        return -1;
    }
    ifstream in(argv[1]);
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    Sales_data total;
    if (read(in, total)) {
        Sales_data trans;
        while (read(in, trans)) {
            if (total.isbn() == trans.isbn()) {
                total.combine(trans);
            } else {
                print(cout, total) << endl;
                total = trans;
            }
        }
        print(cout, total) << endl;
    } else {
        cerr << "没有数据" << endl;
    }
    return 0;
}

int pr_8_7(int argc, char *argv[])
{
    if (argc != 3) {
        cerr << "请给出输入、输出文件名" << endl;
        return -1;
    }
    ifstream in(argv[1]);
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    ofstream out(argv[2]);
    if (!out) {
        cerr << "无法打开输出文件" << endl;
        return -1;
    }
    Sales_data total;
    if (read(in, total)) {
        Sales_data trans;
        while (read(in, trans)) {
            if (total.isbn() == trans.isbn()) {
                total.combine(trans);
            } else {
                print(out, total) << endl;
                total = trans;
            }
        }
        print(out, total) << endl;
    } else {
        cerr << "没有数据" << endl;
    }
    return 0;
}

int pr_8_8(int argc, char *argv[])
{
    if (argc != 3) {
        cerr << "请给出输入、输出文件名" << endl;
        return -1;
    }
    ifstream in(argv[1]);
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    ofstream out(argv[2], ofstream::app);  // 指定打开方式,追加到文件末尾
    if (!out) {
        cerr << "无法打开输出文件" << endl;
        return -1;
    }
    Sales_data total;
    if (read(in, total)) {
        Sales_data trans;
        while (read(in, trans)) {
            if (total.isbn() == trans.isbn()) {
                total.combine(trans);
            } else {
                print(out, total) << endl;
                total = trans;
            }
        }
        print(out, total) << endl;
    } else {
        cerr << "没有数据" << endl;
    }
    return 0;
}

void pr_8_9()
{
    ostringstream msg;
    msg << "C++ Primer 第五版 " << endl;
    istringstream in(msg.str());
    pr_8_1(in);
}

int pr_8_10()
{
    ifstream in("data");
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    string line;
    vector<string> words;
    while (getline(in, line)) {
        words.push_back(line);
    }
    in.close();
    vector<string>::const_iterator it = words.cbegin();
    while (it != words.cend()) {
        istringstream line_str(*it);
        string word;
        while (line_str >> word) {
            cout << word << " ";
        }
        cout << endl;
        ++it;
    }

    return 0;
}

struct PersonInfo
{
    string name;
    vector<string> phones;
};

void pr_8_11()
{
    string line, word;
    vector<PersonInfo> people;
    istringstream record;
    while (getline(cin, line)) {
        PersonInfo info;
        record.clear();  // 重复使用字符串流时，每次都要调用 clear
        record.str(line);
        record >> info.name;
        while (record >> word) {
            info.phones.push_back(word);
        }
        people.push_back(info);
    }
}

string formt(const string &s) { return s; }
bool valid(const string &s) { return true; }
int pr_8_13(int argc, char *argv[])
{
    string line, word;  // 分别保存来自输入的一行和单词
    vector<PersonInfo> people;  // 保存来自输入的所有记录
    istringstream record;
    if (argc != 2) {
        cerr << "请给出文件名" << endl;
        return -1;
    }
    ifstream in(argv[1]);
    if (!in) {
        cerr << "无法打开输入文件" << endl;
        return -1;
    }
    while (getline(in, line)) {
        PersonInfo info;
        record.clear();
        record.str(line);
        record >> info.name;
        while (record >> word) {
            info.phones.push_back(word);
        }
        people.push_back(info);
    }
    ostringstream os;
    for (const auto &entry : people) {
        ostringstream formatted, badNums;
        for (const auto &nums : entry.phones) {
            if (!valid(nums)) {
                badNums << " " << nums;
            } else {
                formatted << " " << formt(nums);
            }
        }
        if (badNums.str().empty()) {
            os << entry.name << " " << formatted.str() << endl;
        } else {
            cerr << "input error: " << entry.name
                 << " invalid number(s)" << badNums.str() << endl;
        }
    }
    cout << os.str() << endl;
    return 0;
}

int main()
{
    pr_8_9();
    return 0;
}
